home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / docs / events.doc < prev    next >
Text File  |  1993-12-06  |  15KB  |  296 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.                                  EVENT QUEUE LIBRARY
  19.  
  20.  
  21.  
  22.                                 for Turbo C and DJGPP
  23.  
  24.                                     User's Manual
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.                                      Written by:
  41.  
  42.                                      Csaba Biegl
  43.                                       May, 1992
  44.  
  45.  
  46.  
  47.  
  48.  
  49.             Event Queue Library User's Manual                               page 2
  50.  
  51.  
  52.           Abstract
  53.  
  54.             This document describes  an event queue library  which can be used in  Turbo C
  55.             and  DJGPP programs.  The event  queue mechanism is  interrupt driven  and the
  56.             queue stores keyboard and mouse events in the order of their arrival. In order
  57.             for the  mouse services of this library to  work an MS compatible mouse driver
  58.             has to be installed on the PC.
  59.  
  60.  
  61.             Introduction -- why event queues?
  62.  
  63.             The "standard" MS-DOS programmer's interface to  the keyboard (via DOS or BIOS
  64.             calls)  and the mouse (via  the mouse driver) has a  couple of shortcomings --
  65.             especially for graphical user interfaces. These are:
  66.  
  67.                  ∙      No mouse event  history: the mouse  driver provides some  services
  68.                         for  the application  program to  poll the mouse  position, button
  69.                         states, etc..  These services can  be adequate if  the application
  70.                         can afford  to spend most of its time  in a tight loop waiting for
  71.                         these  events.  (For  example  a  graphical  editor)  However,  in
  72.                         applications   which   do   lengthy   computations   without  user
  73.                         interaction  this method  can  easily lead  to  the loss  of  user
  74.                         interaction events.
  75.  
  76.                  ∙      Limited mouse  cursor drawing capabilities: the  mouse driver does
  77.                         not support cursor drawing in extended, higher-resolution graphics
  78.                         modes. The solution  is to have the application to draw the cursor
  79.                         after polling the  mouse driver for  the current cursor  position.
  80.                         However, in programs  which spend a  lot of  time not waiting  for
  81.                         user input it will lead to long periods when the cursor is frozen.
  82.  
  83.                  ∙      Limited   keyboard  buffer  size.   Unless  reprogrammed   by  the
  84.                         application the  standard  BIOS keyboard  buffer size  is only  16
  85.                         bytes, which may be insufficient for longer type-ahead sequences.
  86.  
  87.                  ∙      Missing keyboard  modifier keys in  the BIOS buffer:  the standard
  88.                         BIOS  keyboard services  cannot determine  the status  of keyboard
  89.                         modifier  keys for  previously  entered keys.  (It is  possible to
  90.                         obtain these values at the moment the keystroke is received.)
  91.  
  92.             The interrupt driven event queue library described in this  manual attempts to
  93.             solve the above  problems. It stores all user  interaction events (key presses
  94.             and mouse button  changes) in  a FIFO queue  together with the  status of  the
  95.             keyboard modifier keys and a  time stamp of the event. The size  of this queue
  96.             is programmable  by the application,  thus the  queue can be  large enough  to
  97.             avoid event loss.
  98.  
  99.             NOTE: although  this  event  queue library  is  used in  the  LIBGRX  graphics
  100.             library, it is in no way attached  to LIBGRX. The event queue mechanism can be
  101.             used in any Turbo C or DJGPP program.
  102.  
  103.  
  104.  
  105.  
  106.  
  107.             Event Queue Library User's Manual                               page 3
  108.  
  109.  
  110.           Data structures
  111.  
  112.             The application  program can obtain the user  input events in an 'EventRecord'
  113.             structure which is shown  below (all of the following  declarations and macros
  114.             can be found in the include file "eventque.h"):
  115.  
  116.             typedef struct {
  117.                      unsigned char   evt_type;              /* event type: 0: keyboard, 1: mouse */
  118.                      unsigned char   evt_kbstat;            /* keyboard status (ALT, SHIFT, etc..) */
  119.                      unsigned char   evt_mask;              /* mouse event mask */
  120.                      unsigned char   evt_button;            /* button status */
  121.                      unsigned short  evt_xpos;              /* X coord (or keycode if keybd event) */
  122.                      unsigned short  evt_ypos;              /* Y coord */
  123.                      unsigned long   evt_time;              /* time stamp of event */
  124.                  #define evt_keycode evt_xpos               /* reuse this  slot for keybd events !! */
  125.                  } EventRecord;
  126.  
  127.             Various macros have been declared to help in decoding the values in the  slots
  128.             of the event record structure:
  129.  
  130.             /*
  131.                   * event types
  132.                   */
  133.                  #define EVENT_KEYBD       0
  134.                  #define EVENT_MOUSE       1
  135.  
  136.                  /*
  137.                   * MOUSE event flag bits (values in the 'evt_mask' slot)
  138.                   * (also defined in "mousex.h" of the graphics library)
  139.                   */
  140.                  #define M_MOTION          0x001
  141.                  #define M_LEFT_DOWN       0x002
  142.                  #define M_LEFT_UP         0x004
  143.                  #define M_RIGHT_DOWN      0x008
  144.                  #define M_RIGHT_UP        0x010
  145.                  #define M_MIDDLE_DOWN     0x020
  146.                  #define M_MIDDLE_UP       0x040
  147.                  #define M_BUTTON_DOWN     (M_LEFT_DOWN | M_MIDDLE_DOWN | M_RIGHT_DOWN)
  148.                  #define M_BUTTON_UP       (M_LEFT_UP   | M_MIDDLE_UP   | M_RIGHT_UP)
  149.                  #define M_BUTTON_CHANGE   (M_BUTTON_UP | M_BUTTON_DOWN )
  150.  
  151.                  /*
  152.                   * MOUSE button status bits (in the 'evt_button' slot)
  153.                   */
  154.                  #define M_LEFT            1
  155.                  #define M_RIGHT           2
  156.                  #define M_MIDDLE          4
  157.  
  158.                  /*
  159.                   * KEYBOARD status word bits ('evt_kbstat' slot)
  160.                   * (also defined in "mousex.h" of the graphics library)
  161.  
  162.  
  163.  
  164.  
  165.  
  166.                  Event Queue Library User's Manual                                            page 4
  167.  
  168.  
  169.            */
  170.                  #define KB_RIGHTSHIFT     0x01             /* right shift key depressed */
  171.                  #define KB_LEFTSHIFT      0x02             /* left shift key depressed */
  172.                  #define KB_CTRL           0x04             /* CTRL depressed */
  173.                  #define KB_ALT            0x08             /* ALT depressed */
  174.                  #define KB_SCROLLOCK      0x10             /* SCROLL LOCK active */
  175.                  #define KB_NUMLOCK        0x20             /* NUM LOCK active */
  176.                  #define KB_CAPSLOCK       0x40             /* CAPS LOCK active */
  177.                  #define KB_INSERT         0x80             /* INSERT state active */
  178.  
  179.                  #define KB_SHIFT          (KB_LEFTSHIFT | KB_RIGHTSHIFT)
  180.  
  181.             The  event queue is just a circular  buffer of 'EventRecord' structures with a
  182.             header structure as follows:
  183.  
  184.             typedef struct {
  185.                      unsigned short  evq_maxsize;    /* max size of event queue */
  186.                      unsigned short  evq_cursize;    /* number of events in the queue */
  187.                      unsigned short  evq_rdptr;      /* next event to read */
  188.                      unsigned short  evq_wrptr;      /* next event to be written */
  189.                      short    evq_xpos;              /* current X coordinate of mouse */
  190.                      short    evq_ypos;              /* current Y coordinate of mouse */
  191.                      short    evq_xmin;              /* minimal mouse X coordinate */
  192.                      short    evq_ymin;              /* minimal mouse Y coordinate */
  193.                      short    evq_xmax;              /* maximal mouse X coordinate */
  194.                      short    evq_ymax;              /* maximal mouse Y coordinate */
  195.                      short    evq_xspeed;            /* horizontal speed (mickey/coord) */
  196.                      short    evq_yspeed;            /* vertical speed (mickey/coord) */
  197.                      unsigned short  evq_thresh;     /* fast movement threshold */
  198.                      unsigned short  evq_accel;      /* multiplier for fast move */
  199.                      unsigned char   evq_drawmouse;  /* interrupt handler has to draw mouse */
  200.                      unsigned char   evq_moved;      /* set if mouse moved */
  201.                      unsigned char   evq_delchar;    /* character removed from BIOS buffer */
  202.                      unsigned char   evq_enable;     /* event generation control flag */
  203.                      EventRecord     evq_events[1];  /* event buffer space */
  204.                  } EventQueue;
  205.  
  206.             The event  queue circler buffer is  allocated by a library  function (see next
  207.             section).  Its size is  determined at the  time this init  function is called.
  208.             After initialization the application  program receives a pointer to  the queue
  209.             header structure. NOTE: int the case of 32 bit DJGPP programs  the event queue
  210.             is allocated in the dos extender area,  and a pointer into the low memory area
  211.             is returned to the protected mode program.
  212.  
  213.             The  first four  slots  of  the  event  queue  header  ('evq_maxsize'  through
  214.             'evq_wrptr') should never be changed by the application program. These are for
  215.             queue  management  and  are used  by  the  library  internally. The  remaining
  216.             structure  slots of  the header  can  be used  to  control the  mouse and  the
  217.             generation  of events. The 'evq_xpos' and 'evq_ypos' slots contain the current
  218.             mouse  position. The  'evq_xmin' through  'evq_ymax' slots  specify the  mouse
  219.             coordinate limits. The event queue library uses only the mouse mickey counters
  220.  
  221.  
  222.  
  223.  
  224.  
  225.             Event Queue Library User's Manual                               page 5
  226.  
  227.  
  228.           to  calculate the  cursor position.  The reason  for this  is that  some mouse
  229.             drivers perform  the  rounding of  mouse cursor  coordinates   to the  nearest
  230.             multiple of eight if they  find themselves in a text or  unrecognized graphics
  231.             mode.  The 'evq_xspeed' and 'evq_yspeed' slots control the speed of the mouse.
  232.             The mouse mickey  count changes are divided by these values before calculating
  233.             the cursor  position. The 'evq_thresh'  and 'evq_accel'  slots can be  used to
  234.             control the ballistic effect: if the cursor changes by more than the threshold
  235.             the  change  is multiplied  with the  acceleration.  NOTE: most  mouse drivers
  236.             already  provide some  amount of  ballistic effect.  The 'evq_drawmouse'  flag
  237.             controls whether the  interrupt-driven mouse event  handler updates the  mouse
  238.             cursor  or not. The 'evq_moved' slot is  set by the library whenever the mouse
  239.             cursor position changes. An application might clear this slot and then monitor
  240.             its value to detect a mouse movement.
  241.  
  242.             The  'evq_delchar' slot affects the behavior of the keyboard event generation.
  243.             If  this  slot is  set then  the key  code  is removed  from the  BIOS buffer,
  244.             otherwise it is left there (even if an event entry is generated in the queue).
  245.             The  'evq_enable'  slot can  be  used to  individually enable  or  disable the
  246.             generation of mouse and keyboard events. The desired values for  this slot can
  247.             be obtained using the EVENT_ENABLE macro: 
  248.  
  249.             /*
  250.                   * set this bit in 'evq_enable' to enable the generation of the corresponding event
  251.                   * use EVENT_KEYBD or EVENT_MOUSE as argument
  252.                   */
  253.                  #define EVENT_ENABLE(type)        (1 << (type))
  254.  
  255.  
  256.             Library functions
  257.  
  258.             The library contains only the following three functions:
  259.  
  260.             EventQueue *EventQueueInit(int qsize,int ms_stksize,void (*msdraw)(void));
  261.                  void        EventQueueDeInit(void);
  262.                  int         EventQueueNextEvent(EventQueue *q,EventRecord *e);
  263.  
  264.             The  'EventQueueInit' function  initializes  the queue.  The 'qsize'  argument
  265.             specifies  the size  of the  circular  buffer. The  'msdraw'  argument is  the
  266.             function  which is  used  to  update the  mouse  cursor  position whenever  it
  267.             changes. The 'ms_stksize' argument  specifies the size of the  stack necessary
  268.             for the cursor drawing function. If the cursor update function pointer is NULL
  269.             the library  will not  attempt to update  the cursor  position. Otherwise  the
  270.             cursor  update function should obtain  the current mouse  coordinates from the
  271.             queue header 'evq_xpos' and 'evq_ypos'. If the 'evq_drawmouse' slot is cleared
  272.             in the queue header then the mouse cursor drawing function will not be called.
  273.             As mouse interrupts can occur at any  time, the displaying and erasing of  the
  274.             mouse cursor should  be done with some caution. For  display: first the cursor
  275.             should be  drawn and 'evq_drawmouse' should be set only after this. For erase:
  276.             first 'evq_drawmouse' should  be cleared and the cursor erased next. The above
  277.             sequence  assures that  no  spurious mouse  cursor  drawing will  happen.  The
  278.             'evq_drawmouse' slot is cleared after the init function returns.
  279.  
  280.  
  281.  
  282.  
  283.  
  284.             Event Queue Library User's Manual                               page 6
  285.  
  286.  
  287.           The 'EventQueueDeInit' function should be called before the termination of the
  288.             program. NOTE:  it  is very  important to  call this  function before  program
  289.             termination  because a  call to  'EventQueueInit'  hooks some  interrupts (the
  290.             keyboard interrupt and the mouse driver callback function). If these interrupt
  291.             are not reset  to their initial values at program  exit, the interrupt vectors
  292.             will point into the already terminated program -- with disastrous results.
  293.  
  294.             The  'EventQueueNextEvent' function copies the next event entry from the queue
  295.             into the event buffer whose address is passed to it as an argument. It returns
  296.             a non-zero value if these was an event available, zero otherwise.